////////////////////////////////////////////////////////////////////////
// Last svn revision: $Id:  $ 
////////////////////////////////////////////////////////////////////////

#include <math.h>
#include <assert.h>
#include "MLC/Complex.hh"
#include "MLC/DefaultComplexOp.hh"
#include "MLCTest/TDefaultComplexOp.hh"

namespace drow {
namespace test {

void TDefaultComplexOp::TestClass()
{
    TestConjugate();
    TestAdd();
    TestSubtract();
    TestMultiply();
    TestMagSquared();
    TestMag();
    TestAngle();
}

MLC::Complex TDefaultComplexOp::CreateComplex(double re, double im)
{
    MLC::Complex c;
    c.Re = re;
    c.Im = im;
    return c;
}

void TDefaultComplexOp::AssertEquals(const MLC::Complex& a, const MLC::Complex& b)
{
    assert( a.Re == b.Re );
    assert( a.Im == b.Im );
}

void TDefaultComplexOp::TestConjugate()
{
    MLC::def::DefaultComplexOp c;
    AssertEquals( c.ComplexConjugate(CreateComplex(1,0)), CreateComplex(1,0) );
    AssertEquals( c.ComplexConjugate(CreateComplex(0,1)), CreateComplex(0,-1) );
}

void TDefaultComplexOp::TestAdd()
{
    MLC::def::DefaultComplexOp c;
    AssertEquals( c.Add(CreateComplex(1,0), CreateComplex(0,1)), CreateComplex(1,1) );
    AssertEquals( c.Add(CreateComplex(18,-0.2), CreateComplex(0.001,1)), CreateComplex(18.001,0.8) );
    AssertEquals( c.Add(CreateComplex(0,0), CreateComplex(0,0)), CreateComplex(0,0) );
}

void TDefaultComplexOp::TestSubtract()
{
    MLC::def::DefaultComplexOp c;
    AssertEquals( c.Subtract(CreateComplex(1,0), CreateComplex(0,1)), CreateComplex(1,-1) );
    AssertEquals( c.Subtract(CreateComplex(18,-0.2), CreateComplex(0.001,1)), CreateComplex(17.999,-1.2) );
    AssertEquals( c.Subtract(CreateComplex(0.001,1), CreateComplex(0.001,1)), CreateComplex(0,0) );
}

void TDefaultComplexOp::TestMultiply()
{
    MLC::def::DefaultComplexOp c;
    AssertEquals( c.Multiply(CreateComplex(1,0), CreateComplex(0,1)), CreateComplex(0,1) );
    AssertEquals( c.Multiply(CreateComplex(1,1), CreateComplex(1,1)), CreateComplex(0,2) );
}

void TDefaultComplexOp::TestMagSquared()
{
    MLC::def::DefaultComplexOp c;
    assert( c.MagnitudeSquared(CreateComplex(1,0)) == 1 );
    assert( c.MagnitudeSquared(CreateComplex(3,4)) == 25 );
    assert( c.MagnitudeSquared(CreateComplex(0,0)) == 0 );
}

void TDefaultComplexOp::TestMag()
{
    MLC::def::DefaultComplexOp c;
    assert( c.Magnitude(CreateComplex(1,0)) == 1 );
    assert( c.Magnitude(CreateComplex(3,4)) == 5 );
    assert( c.Magnitude(CreateComplex(0,0)) == 0 );
}

void TDefaultComplexOp::TestAngle()
{
    MLC::def::DefaultComplexOp c;
    const double pi = atan(1.0)*4;
    assert( c.Angle(CreateComplex(0,0)) == 0 );
    assert( c.Angle(CreateComplex(1,0)) == 0 );
    //assert( c.Angle(CreateComplex(1,1)) == pi/4 );
    //assert( c.Angle(CreateComplex(0,1)) == pi/2 );
    //assert( c.Angle(CreateComplex(-1,0)) == pi );
    //assert( c.Angle(CreateComplex(0,-1)) == -pi/2 );
}

} // namespace MLC
} // namespace drow
